#include <cstdio>
#define col(c, i) (c * n + i)

const int N = 10004;
int n, m, C, k, a[N * 11], deg[N * 11];

struct Node {
  int fa, ch[2], val;
  bool rev;
} tr[N * 11];

inline bool iden(int x) { return tr[tr[x].fa].ch[1] == x; }

inline bool isnrt(int x) { return tr[tr[x].fa].ch[0] == x || tr[tr[x].fa].ch[1] == x; }

inline void pushup(int x) {
  static int ls, rs;
  ls = tr[x].ch[0], rs = tr[x].ch[1];
  tr[x].val = a[x];
  if (ls && tr[ls].val > tr[x].val) tr[x].val = tr[ls].val;
  if (rs && tr[rs].val > tr[x].val) tr[x].val = tr[rs].val;
}

inline void reverse(int x) {
  static int tmp;
  tmp = tr[x].ch[0];
  tr[x].ch[0] = tr[x].ch[1];
  tr[x].ch[1] = tmp;
  tr[x].rev ^= 1;
}

inline void pushdown(int x) {
  if (tr[x].rev) {
    if (tr[x].ch[0]) reverse(tr[x].ch[0]);
    if (tr[x].ch[1]) reverse(tr[x].ch[1]);
    tr[x].rev = false;
  }
}

inline void pushall(int x) {
  if (isnrt(x)) pushall(tr[x].fa);
  pushdown(x);
}

inline void rotate(int x) {
  bool xtofa = iden(x);
  int fa = tr[x].fa, ffa = tr[fa].fa, son = tr[x].ch[!xtofa];
  if (isnrt(fa)) tr[ffa].ch[iden(fa)] = x;
  tr[x].fa = ffa;
  tr[x].ch[!xtofa] = fa;
  tr[fa].ch[xtofa] = son;
  if (son) tr[son].fa = fa;
  tr[fa].fa = x;
  pushup(fa);
}

inline void splay(int x) {
  pushall(x);
  for (int fa; isnrt(x); rotate(x))
    if (isnrt(fa = tr[x].fa)) rotate(iden(fa) == iden(x) ? fa : x);
  pushup(x);
}

inline void access(int x) {
  for (int y = 0; x; y = x, x = tr[x].fa) splay(x), tr[x].ch[1] = y, pushup(x);
}

inline void makert(int x) { access(x), splay(x), reverse(x); }

inline int findrt(int x) {
  access(x), splay(x);
  while (tr[x].ch[0]) pushdown(x), x = tr[x].ch[0];
  splay(x);
  return x;
}

inline void cut(int x, int y) {
  deg[x]--, deg[y]--;
  makert(x), access(y), splay(y);
  tr[x].fa = tr[y].ch[0] = 0;
  pushup(y);
}

inline void link(int x, int y) {
  deg[x]++, deg[y]++;
  makert(x), tr[x].fa = y;
}

inline void split(int x, int y) { makert(x), access(y), splay(y); }

inline void modifycol(const int &x, const int &y, const int &c) {
  for (int j = 0; j < C; ++j) {
    if (findrt(col(j, x)) == findrt(col(j, y))) {
      split(col(j, x), col(j, y));
      if (tr[col(j, y)].ch[0] != col(j, x) || tr[col(j, x)].ch[1]) continue;

      if (j == c) return puts("Success."), void();

      if (deg[col(c, x)] == 2 || deg[col(c, y)] == 2) return puts("Error 1."), void();

      else if (findrt(col(c, x)) == findrt(col(c, y))) {
        return puts("Error 2."), void();
      } else {
        cut(col(j, x), col(j, y)), link(col(c, x), col(c, y));
        return puts("Success."), void();
      }
    }
  }
  puts("No such edge.");
}

inline int query(const int &x, const int &y, const int &c) {
  if (findrt(col(c, x)) == findrt(col(c, y))) {
    split(col(c, x), col(c, y));
    return tr[col(c, y)].val;
  } else
    return -1;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("P2173 [ZJOI2012]网络.in", "r", stdin);
  freopen("P2173 [ZJOI2012]网络.out", "w", stdout);
#endif
#endif

  scanf("%d%d%d%d", &n, &m, &C, &k);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &a[i]);
    for (int j = 1; j < C; ++j) a[col(j, i)] = a[i];
  }
  for (int i = 1, u, v, w; i <= m; ++i) {
    scanf("%d%d%d", &u, &v, &w);
    link(col(w, u), col(w, v));
  }
  for (int i = 1, opt, x, y, c; i <= k; ++i) {
    scanf("%d", &opt);
    switch (opt) {
      case 0:
        scanf("%d%d", &x, &y);
        for (int j = 0; j < C; ++j) {
          access(col(j, x));
          splay(col(j, x));
          a[col(j, x)] = y;
          pushup(col(j, x));
        }
        break;
      case 1:
        scanf("%d%d%d", &x, &y, &c);
        modifycol(x, y, c);
        break;
      default:
        scanf("%d%d%d", &c, &x, &y);
        printf("%d\n", query(x, y, c));
    }
  }
  return 0;
}